`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    19:01:57 05/04/2013 
// Design Name: 
// Module Name:    RegisterSet 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
//module RegisterSet #(parameter N = 4) (
//    input [N - 1 : 0] data_in,
//    input [1 : 0] addr_in,
//	 input [1 : 0] read_addr_in,
//	 input [1 : 0] dstAddr,
//	 input [1 : 0] srcASel,
//	 input [1 : 0] srcBSel,
//    input ldr,
//	 input sum,
//	 input cmp,
//	 input mul,
//    input [(2 * N) - 1 : 0] alu_data_in,
//    input read,
//	 output reg [N - 1 : 0] REGA,
//	 output reg [N - 1 : 0] REGB,
//    output reg [N - 1 : 0] data_out
//    );
//	 
//	 reg [N - 1 : 0] reg_A;
//	 reg [N - 1: 0] reg_B;
//	 reg [N - 1: 0] reg_C;
//	 reg [N - 1: 0] reg_D;
//	 
//	 //reg [7 : 0] alu_data = 0;
//	 /*reg [1 : 0] dstAddr = data_in[3:2];
//	 reg [1 : 0] srcASel = data_in[5:4];
//	 reg [1 : 0] srcBSel = data_in[7:6];*/
//	 
//	 always @(*) begin
//		// Load
//		if (ldr) begin
//			case (addr_in) 
//				2'b00 : reg_A <= data_in;				
//				2'b01 : reg_B <= data_in;
//				2'b10 : reg_C <= data_in;
//				2'b11 : reg_D <= data_in;
//			endcase
//		end
//		// SUM block
//		else if (sum) begin
//			case (dstAddr)
//				2'b00 : reg_A <= #5 (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];				
//				2'b01 : reg_B <= #5 (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//				2'b10 : reg_C <= #5 (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//				2'b11 : reg_D <= #5 (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//			endcase
//			case (srcASel)
//				2'b00 : REGA <= reg_A;				
//				2'b01 : REGA <= reg_B;
//				2'b10 : REGA <= reg_C;
//				2'b11 : REGA <= reg_D;
//			endcase
//			case (srcBSel)
//				2'b00 : REGB <= reg_A;				
//				2'b01 : REGB <= reg_B;
//				2'b10 : REGB <= reg_C;
//				2'b11 : REGB <= reg_D;
//			endcase
//		end
//		// CMP block
//		else if (cmp) begin
//			case (dstAddr)
//				2'b00 : reg_A <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];			
//				2'b01 : reg_B <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//				2'b10 : reg_C <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//				2'b11 : reg_D <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//			endcase
//			case (srcASel)
//				2'b00 : REGA <= reg_A;				
//				2'b01 : REGA <= reg_B;
//				2'b10 : REGA <= reg_C;
//				2'b11 : REGA <= reg_D;
//			endcase
//			case (srcBSel)
//				2'b00 : REGB <= reg_A;				
//				2'b01 : REGB <= reg_B;
//				2'b10 : REGB <= reg_C;
//				2'b11 : REGB <= reg_D;
//			endcase
//		end
//		// MUL block
//		else if (mul) begin
//			case (dstAddr)
//				2'b00 : reg_A <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];			
//				2'b01 : reg_B <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//				2'b10 : reg_C <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//				2'b11 : reg_D <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
//			endcase
//			case (srcASel)
//				2'b00 : REGA = reg_A;				
//				2'b01 : REGA = reg_B;
//				2'b10 : REGA = reg_C;
//				2'b11 : REGA = reg_D;
//			endcase
//			case (srcBSel)
//				2'b00 : REGB = reg_A;				
//				2'b01 : REGB = reg_B;
//				2'b10 : REGB = reg_C;
//				2'b11 : REGB = reg_D;
//			endcase
//		end
//	end
//	
//	always @(posedge read) begin
//		if (alu_data_in > 15) begin
//			case (read_addr_in)
//					2'b00 : data_out <= reg_A;				
//					2'b01 : data_out <= reg_B;
//					2'b10 : data_out <= reg_C;
//					2'b11 : data_out <= reg_D;
//			endcase
//		end
//		
//		else begin
//			case (read_addr_in)
//				2'b00 : data_out <= reg_A;				
//				2'b01 : data_out <= reg_B;
//				2'b10 : data_out <= reg_C;
//				2'b11 : data_out <= reg_D;
//			endcase
//		end
//	end
//	 
//	 /*assign REGA = reg_A[3:0];
//	 assign REGB = reg_B[3:0];*/
//
//
//endmodule
module RegisterSet #(parameter N = 4) (
    input [N - 1 : 0] data_in,
    input [1 : 0] addr_in,
    input ldr,
    input [(2 * N) - 1 : 0] alu_data_in,
    input read,
	 input write_to_reg,
	 input clk,
	 input rst,
	 input [1 : 0] sev_seg_read_addr,
	 output reg [N - 1 : 0] REGA,
	 output reg [N - 1 : 0] REGB,
    output reg [N - 1 : 0] data_out
    );
	 
	 reg [3:0] reg_A;
	 reg [3:0] reg_B;
	 reg [3:0] reg_C;
	 reg [3:0] reg_D;
	 
//	 reg test = 1'b0;
	 
	 always @(posedge clk, negedge rst) begin
		if (!rst)
			begin
				reg_A <= 1'b0;
				reg_B <= 1'b0;
				reg_C <= 1'b0;
				reg_D <= 1'b0;
			end
		else
			begin
				if (ldr) begin
					case (addr_in)
						2'b00 : reg_A <= data_in;
						2'b01 : reg_B <= data_in;
						2'b10 : reg_C <= data_in;
						2'b11 : reg_D <= data_in;
					endcase
				end
				else begin
					case (data_in[1:0])
						2'b00 : REGA <= reg_A;
						2'b01 : REGA <= reg_B;
						2'b10 : REGA <= reg_C;
						2'b11 : REGA <= reg_D;
					endcase
					case (data_in[3:2])
						2'b00 : REGB <= reg_A;
						2'b01 : REGB <= reg_B;
						2'b10 : REGB <= reg_C;
						2'b11 : REGB <= reg_D;
					endcase
//					test <= 1'b1;
				end
				if (write_to_reg) begin
					case (addr_in)
						2'b00 : reg_A <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
						2'b01 : reg_B <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
						2'b10 : reg_C <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
						2'b11 : reg_D <= (alu_data_in > 15) ? alu_data_in[7:4] : alu_data_in[3:0];
					endcase
				end
				if (read) begin
					case (sev_seg_read_addr)
							2'b00 : data_out <= reg_A;				
							2'b01 : data_out <= reg_B;
							2'b10 : data_out <= reg_C;
							2'b11 : data_out <= reg_D;
					endcase
				end
			end
	 end
endmodule
